import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

public class ProducerConsumer {
	private static final int BOUND = 16;
	private static final int N_CONSUMERS = 8;

	private static void interruptIndexers(List<Thread> indexerPool) {
		for (Thread indexerThread : indexerPool) {
			indexerThread.interrupt();
		}
	}

	public static void startIndexing(File[] roots) {
		@SuppressWarnings("unchecked")
		BlockingDeque<File>[] dequeues = new BlockingDeque[N_CONSUMERS];

		for (int i = 0; i < dequeues.length; i++) {
			dequeues[i] = new LinkedBlockingDeque<File>(BOUND);
		}

		FileFilter filter = new FileFilter() {
			public boolean accept(File file) {
				return true;
			}
		};

		final List<Thread> indexerPool = new ArrayList<Thread>();

		for (int i = 0; i < N_CONSUMERS; i++) {
			Thread t = new Thread(new Indexer(dequeues, i), "indexer-" + i);
			t.start();
			indexerPool.add(t);
		}

		CountDownLatch latch = new CountDownLatch(roots.length);

		int crawlerIndex = 0;
		for (File root : roots) {
			Thread crawler = new Thread(new FileCrawler(dequeues, filter, root,
					latch), "Crawler-" + crawlerIndex);
			crawlerIndex++;
			crawler.start();
		}

		try {
			latch.await();
			interruptIndexers(indexerPool);
		} catch (InterruptedException e) {
			System.out.println("Was interrupted, while awaiting for latch.");
		}
	}
}